package com.ljx.blog.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljx.blog.common.domain.vo.resp.PageResp;
import com.ljx.blog.common.enums.CommonStatusTypeEnum;
import com.ljx.blog.common.exception.ApiException;
import com.ljx.blog.security.util.UserUtil;
import com.ljx.blog.user.domain.entity.Role;
import com.ljx.blog.user.domain.vo.req.RolePageReq;
import com.ljx.blog.user.domain.vo.req.RoleSubmitReq;
import com.ljx.blog.user.domain.vo.req.RoleToUserReq;
import com.ljx.blog.user.mapper.RoleMapper;
import com.ljx.blog.user.service.RoleService;
import com.ljx.blog.user.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2024-10-03  21:35
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;


    @Override
    public List<Long> getUserRoleIdByUserId(Long userId) {
        return roleMapper.getUserRoleByUserId(userId);
    }

    @Override
    public List<Role> getRoleByIds(List<Long> roleIds) {
        return listByIds(roleIds);
    }

    @Override
    public Boolean checkRole(String code) {
        return checkUserRole(UserUtil.getUserId(), code);
    }

    @Override
    public Boolean checkUserRole(Long userId, String code) {
        return roleMapper.checkUserRoleByCode(userId, code) >= 1;
    }

    @Override
    public void initUserRole(Long userId, Long roleId) {
        roleMapper.insertUserRole(userId, roleId);
    }

    @Override
    public Role getRoleByName(String roleName) {
        return roleMapper.selectOne(new LambdaQueryWrapper<Role>()
                .eq(Role::getName, roleName)
                .eq(Role::getStatus, CommonStatusTypeEnum.NORMAL.getKey()));
    }


    @Override
    public List<Role> getRoleLikeName(String roleName) {
        return roleMapper.selectList(new LambdaQueryWrapper<Role>()
                .eq(Role::getStatus, CommonStatusTypeEnum.NORMAL.getKey())
                .like(Role::getName, roleName));
    }

    @Override
    public PageResp<Role> getPage(RolePageReq req) {
        LambdaQueryWrapper<Role> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(req.getKey())){
            lambdaQueryWrapper.like(Role::getName, req.getKey());
        }
        Page<Role> page = roleMapper.selectPage(new Page<>(req.getCurrPage(), req.getPageSize()), lambdaQueryWrapper);
        return PageResp.<Role>builder()
                .total(page.getTotal())
                .list(page.getRecords())
                .build();
    }

    @Override
    public Role submit(RoleSubmitReq req) {
        Role role;
        if (Objects.isNull(req.getId())){
            role = BeanUtil.copyProperties(req, Role.class);
            roleMapper.insert(role);
        } else {
            role = roleMapper.selectById(req.getId());
            BeanUtils.copyProperties(req, role);
            roleMapper.updateById(role);
        }

        return role;
    }

    @Override
    @Transactional
    public void allocationToUser(RoleToUserReq req) {
        checkPermission(req);
        roleMapper.deleteUserRole(req.getUserId());
        for (Long roleId : req.getRoleIds()) {
            roleMapper.insertUserRole(req.getUserId(), roleId);
        }
    }

    private void checkPermission(RoleToUserReq req) {
        Long userTenantId = UserUtil.tryToGetUserTenantId(req.getUserId());
        Long tenantId = UserUtil.tryToGetTenantId();
        if (tenantId.equals(userTenantId)){
            throw new ApiException("权限不足");
        }
    }
}
